Integrate native runtime, redesigned world, and canonical humanoids - #15
Open
lyc-aon wants to merge 128 commits into
Open
Integrate native runtime, redesigned world, and canonical humanoids#15lyc-aon wants to merge 128 commits into
lyc-aon wants to merge 128 commits into
Conversation
The debug character builder ("blue frog") is now accessible via converse with
GR0K or when opening converse with no target under `--features dev-tools`.
Unlike Core3's single-select SUI, leaves are multi-select checkboxes so a
tester can tick multiple items, packs, or skills and commit them via GRANT
SELECTED in one action.
The catalog (173 items, 126 skills, 7 packs) is generated by
`crates/successor-sim/src/bin/emit_debug_catalog.rs` probing the runtime tables,
embedded via `include_str!`, and checked by `tools/successor/assets/fix_glb_pbr.py`
and the hygiene gate. Added `ClientCommand::DebugGiveCredits { amount }` (kind 98)
across net, sim, bridge, and server protocol schemas. Debug grants are exempted
from session rate-limiting when `GAME_DEBUG_AUTHORITY_COMMANDS=1` is set.
Inventory radial: right-clicks over interactive windows were swallowed by `covers()`
before reaching the radial branch. Now resolved above the swallow, opening the
object radial with UNEQUIP, EXAMINE, DISCARD, SPLICE. Relabelled DROP to DISCARD
to match DiscardStack semantics.
Converse NPC bust: camera facing calculation now dead-ons the speaker's front
(yaw + PI) instead of following pawn yaw (which showed the back of turned NPCs).
Trainer detection range widened to 16 cells with in_range gating preserved.
Viewer seat alpha lowered from 245 to 28 so 3D composite cells blend with
translucent window backgrounds. Added fill light to ItemPreviewRenderer.
A ConnectedScene is constructed before its first framebuffer exists, so `framebuffer` starts at the (1280, 720) placeholder. `load_persisted` ran before any real frame and matched the saved layout's viewport stamp against that placeholder, so a 720p document looked authoritative and its rects were applied verbatim. The first real frame then set the live size but found no pending HUD slots, so nothing re-anchored: on a 1600x1000 window the whole bottom band -- chat console, notifications, ground radar -- stayed pinned to y=720, floating mid-screen. The decision cannot be made at restore time. Restore now applies saved rects unconditionally and records the document's viewport stamp; `frame` compares that stamp against the real framebuffer and re-anchors the band when they disagree. That covers both the startup case and a live window resize. `hud_surfaces_re_anchor_when_the_framebuffer_changes` passed throughout, because it only ever drove `register_hud_surfaces_at` with an explicit viewport -- the one path production never takes. It now asserts the stamp comparison directly and proves the stranded-mid-screen state before the reconcile pulls the band back to the edge. Verified live: at a 1600x1000 framebuffer the band bottoms out at 992, and at 1728x1052 (macOS clamped the 1920x1200 request) it bottoms out at 1044 and right-aligns to 1728 -- the HUD follows the real framebuffer, not the request.
Wave 6 documents the framebuffer anchoring regression and the measured before/after. It also retracts the in-game verification filed for Wave 5: the local authority's Rust bridge had exited, so the shard served a frozen world and closed every join with 1011, and the three screenshots kept as proof are crops of the PLANETFALL loading screen. The Wave 5 code and its green gates stand. Its runtime claims do not, and the surfaces it touched are listed as needing a live pass.
An idle native client was disconnected within the Colyseus liveness window, every time. It survived only while something was actively driving it, which is why this kept reading as intermittent: an agent journey sending control input flushed the socket as a side effect, and a client left alone died. `ws_poll` answered a server Ping with a bare `WsEvent::None` and the comment "tungstenite handles responder automatically". Tungstenite queues the Pong; it only reaches the socket on the next write or flush. A moving player's outbound commands flushed it incidentally. A standing player sent nothing, the pong never left, and Colyseus terminated the connection for missed liveness -- an abrupt reset with no close frame. The Ping arm now flushes, treating WouldBlock as ordinary backpressure and any other error as a transport failure. Two diagnostics that hid this are fixed alongside, because both discarded the cause and left only "reconnect 1/5" on stderr: - a server Close frame's code and reason are printed, which is how `1011 durable character entry failed` becomes visible at all; - the tungstenite error behind `WsEvent::Error` is printed. With those the failure reads directly as `Broken pipe` followed by `Connection reset without closing handshake`. Verified: an idle client held `game_connection: Connected` against `sessionCount: 1` across 89 seconds and ~2,250 ticks, having previously dropped within seconds of going idle. 428 client tests, clippy -D warnings, and the rust hygiene gate stay green.
d57ff3f moved item GLB loads onto AssetStreamer, but changed_path latched lane identity on the first frame, so a lane whose fetch returned Pending never re-requested: inventory cards stayed dark while examine (requesting after the bytes had landed) still worked. Lanes now carry the unsettled path and keep asking until assign_model records the result; a miss whose UNKNOWN_MODEL placeholder is itself still in flight stays unsettled too. Steady-state frames stay allocation-free once a lane settles. Proof: control-server journey on the local authority — inventory opens with all 19 held stacks rendering 3D previews (was: every card dark).
Ground-up rewrite of every screen. The design system ports the game client's window grammar — translucent panels under a bright accent perimeter, caption bands, corner survey ticks, evidence plaques, underline verbs, tracked micro-caps — with oklab color-mix lines and glass throughout, and cuts the copy to the bone. Five keyed themes: DAWN (default) is the site's own daylight glass; SIGNAL/PHOSPHOR/AMBER/OXIDE are byte-exact ports of hud.rs THEMES, selectable from a deck in the topbar and persisted per visitor. The theme-contract suite now reads hud.rs directly, so client palette drift fails the site build. Home rebuilds the intro as an instrument sequence: live cinematic reel under a theme-keyed veil, field-record plates (including two native Rust client captures with provenance in the media manifest), the real 80x24 TUI frame with a staggered opening crawl, and a chrome demo window. The terminal fixture's off-world resource name is corrected to this world's Daxmere iron. Tests: 178 passing, all budgets met (home HTML+CSS 9.0KB gz, cold 118KB). CSP inline-style ban kept; storage hygiene extended with a ruled theme-preference exception.
…ab/1/2 keys Combat FX went dark on the live wire: the server ships combat events as GameCompactCombatEvent tuples (shard.ts sends events: [] beside compactEvents since the size-reduction wave), but CombatEvent::from_json only read the verbose object shape, so every muzzle flash, tracer, outcome burst, floating hit text, and combat SFX cue was silently dropped while receipts kept ammo and vitals honest. from_json now recognizes the tuple layout (indices mirrored from protocol.ts) and both wire shapes feed one shared presentation derivation; four new tests pin tuple/object equivalence, kill boosts, shield precedence, and id-less drops. Looting: F only consulted store.player_corpses, so an authority-marked rogue corpse (lootable, rights held) never opened the loot window. The key handler now falls back to the nearest lootable actor corpse within reach, and the loot projection builds the corpse:<actor-id> container view from the actor snapshot with rights checked against lootRightsActorId. Input: Tab (cycle live targets by distance, wrapping from the current selection) and Digit1/Digit2 (basic/aimed shot through the shared shot_action body) join CONNECTED_INPUT_KEYS, making the README's documented bindings true on both hosts and reachable from the control server. Proof: 439 unit tests pass; live Bunker re-verification follows.
…ll bind sampling The toolbar owns every number-row key (press_code_result runs before the key match), so the documented 1/2 combat bindings could never fire: a fresh install shipped all-empty slots, and worse, only Digit1/Digit2 of the twelve bind keys were even sampled by the connected host — toolbar keybinds worked from clicks alone. CONNECTED_INPUT_KEYS now samples the whole shipped bind row (Digit1..Digit0; Minus/Equal have no Key variant yet and stay click-only), fresh installs get the original's number-row grammar via ToolbarDoc::default_loadout() — ATTACK on 1, the new AIMED SHOT verb on 2 — and both combat verbs route through shot_action, so they inherit nearest-hostile fallback targeting instead of demanding a prior selection. Persisted docs are untouched: from_json still overlays a blank() base, so a deliberately emptied slot stays empty. 439 unit tests pass.
ToolbarDoc::load treated a missing persisted section as blank(), so the default_loadout only survived until the preferences load pass replaced the constructor's toolbar — a fresh profile still showed empty 1/2 slots. A missing section now loads default_loadout(); a present doc (including a deliberately emptied bar) is untouched. 439 tests pass.
Authority image 47abcfe6 (movement ingress budgets, room messages, pong flush), Rust beta successor-rust-beta@e1e0e44caa38b1d1 (compact combat-event decode, NPC corpse looting, inventory preview retry, Tab targeting, number-row toolbar with fresh-install combat loadout), and the rewritten five-theme site. State untouched; generation unchanged. Evidence seal f9d837dec8faed775e1fc7c9c02a8af4b2489d994b413d2e22738fb 70a863b10. Records the farm host-availability waiver and the operational drift found during the promotion.
frame() cleared hud_actions before build_hud, so RunVerb/ToggleWindow actions pushed by handle_key's toolbar branch (host loop, pre-frame) were discarded every frame — number-row keys played the ToolbarUse cue and did nothing, while pointer clicks (pushed during build_hud, after the clear) worked. The drain already leaves the vec empty; drop the early clear. 439 tests pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
dev/rust-clientVerification
pnpm run cimake -C client-rust verifypnpm hygiene:rust(hard gates pass; cargo-machete unavailable and reported as skipped)pnpm desktop:build && pnpm --dir desktop verify:key-ownership2c486e517ac1dac19acfa3d72aba69717bf35ce3ecaae3f9705174d70a31eae99c954d9c7ea72644c9d22ca83a14361843b9d523